package com.dhcc.DRGsHosp.facade.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.inject.Named;

import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.network.InetAddresses;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.openkoala.security.shiro.CurrentUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSON;
import com.dhcc.DRGsHosp.application.SystemConfigApplication;
import com.dhcc.DRGsHosp.facade.CaseGlobalSearchFacade;
import com.dhcc.DRGsHosp.facade.DrgsIndexCalFacade;
import com.dhcc.DRGsHosp.facade.EsRestTempFacade;
import com.dhcc.DRGsHosp.facade.dto.ESDTO;
import com.dhcc.DRGsHosp.infra.util.DrgsIndex;
import com.dhcc.DRGsHosp.infra.util.StringUtils;

/**
 * 
 * @ClassName: FileUploadFacadeImpl  
 * @Description ：    指标计算实现层
 * @Date: 2017年5月8日 下午2:53:07  
 * @Author LiuHongJun 
 * @Version 2.5.0 DHC-DRGs
 */
@Named("caseGlobalSearchFacadeImpllqy20170718")
public class CaseGlobalSearchFacadeImpl implements CaseGlobalSearchFacade {

    private static final Logger logger = LoggerFactory.getLogger(CaseGlobalSearchFacadeImpl.class);
	@Autowired
	private SystemConfigApplication systemConfigApplication;
	
	@Autowired
	private DrgsIndexCalFacade drgsIndexCalFacade;
	
	@Autowired
	private EsRestTempFacade esRestTempFacade;
	
	private TransportClient client=null;
	
	
	/**  
	 *  @Description：调用ES服务，获取数据
	 *  @Author：liuhongjun 
	 *  @see com.dhcc.DRGsHosp.facade.CaseGlobalSearchFacade#getEsData(com.dhcc.DRGsHosp.facade.dto.ESDTO)
	 */
	@Override
	public Map<String, Object> getEsData(ESDTO esDto) {
		Map<String, Object> caseTotalResultMap = new HashMap<>();
		String dateFrom=esDto.getDateFrom();
		String dateTo=esDto.getDateTo();
		String hospCode=esDto.getHospCode();
		String matchingField=esDto.getMatchingField();
		String keyword=esDto.getKeyword();
		int iDisplayStart=esDto.getiDisplayStart();
		int pageSize=esDto.getPageSize();
		String mrType=esDto.getMrType();
		String medinsType=esDto.getMedinsType();
		try {
	        List<Map<String, Object>> caseResultList = new ArrayList<>();
	        String userId=CurrentUser.getUserAccount();
	        String roleId =DrgsIndex.getRoleCode();
	        String mouldeId="groupScheme_"+userId+"_"+roleId;
	        String groupScheme= systemConfigApplication.getSystemGroupScheme(mouldeId,userId, roleId);
	        String stdID = drgsIndexCalFacade.getStdID( dateFrom, dateTo);
	        String verRegion="";
			Map<String,Object> esMap=getEsInfo("es_casesearch");
	        if(StringUtils.hasLength(groupScheme) && groupScheme.split("θ").length>1){
	        	verRegion=groupScheme.split("θ")[0];
	        }
	        logger.info("region_code是： " +verRegion);
	        BoolQueryBuilder qb = QueryBuilders.boolQuery();
	        qb.should(new QueryStringQueryBuilder(verRegion).field("region_code"));
	        if("hcCase".equals(mrType)) {
	        	if("all".equals(medinsType)) {
		    		   BoolQueryBuilder qbAll = QueryBuilders.boolQuery();
		    		   qbAll.should( QueryBuilders.boolQuery().must(QueryBuilders.existsQuery("medinsType")));
		    		   qb.must(qbAll);
	        	}else {
			        qb.must(new QueryStringQueryBuilder(medinsType).field("medinsType"));
	        	}
	        }
	    	if(StringUtils.hasLength(hospCode)){
	    		BoolQueryBuilder qbHosp = QueryBuilders.boolQuery();
	    		String[] hospArr = hospCode.split(",");
	    		for(int i = 0;i<hospArr.length;i++){
	    			qbHosp.should(new QueryStringQueryBuilder(hospArr[i]).field("hospcode"));
	    			 logger.info("医院编码是： " +hospArr[i]);
	    		}
	    		qb.must(qbHosp);
	    	}
	    	if(StringUtils.hasLength(stdID)){
	    		   BoolQueryBuilder qbAll = QueryBuilders.boolQuery();
	    		   //asid为null或具体值的时候
	    		   qbAll.should(new QueryStringQueryBuilder(stdID).field("asid"));
	    		   qbAll.should( QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery("asid")));
	    		   qb.must(qbAll);
	    	}
			 logger.info("asid是： " +stdID);
	    	if (StringUtils.hasLength(matchingField) && StringUtils.hasLength(keyword)) {
	        	BoolQueryBuilder qbAll = QueryBuilders.boolQuery();
	        	String[] fields = matchingField.split(",");
	        	for (String field : fields) {
	        		qbAll.should(new QueryStringQueryBuilder(keyword).field(field));
	        		
				}
	        	qb.must(qbAll);
	        }else if(StringUtils.hasLength(keyword)) {
	          BoolQueryBuilder qbAll = QueryBuilders.boolQuery();
				//es索引字段
				String filed =esMap.get("ES_FILDES")==null?"":esMap.get("ES_FILDES").toString();
				String str="{ ";
				str+=filed+" }";
				Map<String,Object> map = (Map<String, Object>) JSON.parse(str);
	        	Set<String> fields =map.keySet();
	        	for (String field : fields) {
	        		String value=map.get(field)+"";
	        		if(value.contains("ik_max_word")) {
	        	       	qbAll.should(new QueryStringQueryBuilder(keyword).field(field)); 	
	        		}
				}
	        	qb.must(qbAll);
	        }
	    	
	        //设置高亮
	        HighlightBuilder hiBuilder=new HighlightBuilder();
	        hiBuilder.preTags("<span style=\"color:red\">").postTags("</span>").field("*");
			String esServerIps =esMap.get("ES_SERVERIP")==null?"":esMap.get("ES_SERVERIP").toString();
			//ES服务端口，默认9300
			String esServerPort =esMap.get("ES_PORT")==null?"9300":esMap.get("ES_PORT").toString();
			if(client==null) {
				client=	transportClient("es_casesearch",esServerIps,esServerPort);
			}
	        //判断服务为空
			if(client==null) {
		        caseTotalResultMap.put("error", "true");
				return caseTotalResultMap;
			}
			// 通过某个字段查询,例如uid, country  
	        SearchRequestBuilder builder = client.prepareSearch("es_casesearch").setTypes("doc").setSearchType(SearchType.DEFAULT).setFrom(iDisplayStart).setSize(pageSize);  
	    	if(StringUtils.hasLength(dateFrom) && StringUtils.hasLength(dateTo)){ 
	    		qb.must(QueryBuilders.rangeQuery("outdate").format("yyyy-MM-dd").gte(dateFrom).lte(dateTo));
	    	}
	        builder.setQuery(qb);
	        builder.highlighter(hiBuilder);
	        SearchResponse response = builder.execute().actionGet(); 
	        //查询出来的数量
	        long numFound = response.getHits().getTotalHits();
	        //遍历搜索记录
	        for(SearchHit searchHit:response.getHits()){            
	        	Map<String, Object> source = searchHit.getSource();
		        for (String key:searchHit.getSource().keySet()){
		        	//处理高亮片段 
		        	HighlightField highlightField=searchHit.getHighlightFields().get(key);
		            if (highlightField!=null){
		                Text[]fragments=highlightField.fragments();
		                String value="";
		                for (Text text:fragments){
		                    value+=text;
		                }
                        //替换为高亮字段
                        source.put(key,value);
		             }
		        }            
		        caseResultList.add(source);        
	        }
	        caseTotalResultMap.put("caseTotalCount", numFound);
	        caseTotalResultMap.put("caseData", caseResultList);   
	        caseTotalResultMap.put("esindex", "es_casesearch");  
	        caseTotalResultMap.put("groupScheme",verRegion);  
	        caseTotalResultMap.put("asId", stdID);  
			return caseTotalResultMap;
		} catch (Exception e) {
			e.printStackTrace();
			caseTotalResultMap.put("error", e.getMessage());
			logger.error(e.getMessage());
			return caseTotalResultMap;
		}
	}
	/**
	 *  @Discription：获取es服务
	 *  @Author： liuhongjun
	 *  @param esindex
	 *  @return
	 *  @Date:2018年10月30日下午4:04:01
	 */
	public Map<String,Object> getEsInfo (String esindex){
		List<Map<String,Object>> list =esRestTempFacade.getEsInfo(esindex);
		Map<String,Object> map=null;
		if(!StringUtils.isEmpty(list)) {
			map=list.get(0);
		}
		return map;
	}
	/**
	 *  @Discription：获取ES服务
	 *  @Author： liuhongjun
	 *  @Date:2018年5月25日下午2:15:33
	 */
	public TransportClient transportClient(String esIndex,String ip,String port) {
		TransportClient transportClient = null;
		try {
			Settings settings = Settings.builder().put("cluster.name", "drges")// 集群名
					.put("client.transport.sniff", true).build(); // 自动把集群下的机器添加到列表中
			transportClient = new PreBuiltTransportClient(settings);
			String esIps[] = ip.split(",");
			for (String esIp : esIps) {// 添加集群IP列表
				TransportAddress transportAddress = new InetSocketTransportAddress(InetAddresses.forString(esIp), Integer.valueOf(port));
				transportClient.addTransportAddresses(transportAddress);
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage());
			if (transportClient != null) {
				transportClient.close();
			}
			return null;
		}
		return transportClient;
	}
}
